package com.yanqu.road.server.manger.activity.peakseacraft;

import com.yanqu.road.entity.activity.peakseacraft.config.PeakSeacraftActivityConfig;
import com.yanqu.road.entity.activity.seacraft.config.SeacraftSouthSeaActivityConfig;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.enums.eUnionSyncType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.entity.union.cross.CrossUnionInfo;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.activity.PeakSeacraftProto;
import com.yanqu.road.pb.union.UnionProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.peakseacraft.PeakSeacraftModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.manger.union.GameUnionActivityGroupMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.mina.util.ConcurrentHashSet;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class PeakSeacraftGroup {
    private int activityId;
    private int unionGroup;

    /**
     * 晋级名单
     */
    private List<String> joinUnionList = new ArrayList<>();

    // 需要上传玩家派遣对象 k:userId k:系统id v 对象集合
    private ConcurrentHashMap<Long, Set<Integer>> needUploadObjectInfoMap = new ConcurrentHashMap<>();

    /**
     * 在南海丝路 系统里面的玩家k=area*100+group
     */
    private Map<Integer, Set<Long>> inActivitySet = new ConcurrentHashMap<>();

    public PeakSeacraftGroup(int activityId, int unionGroup) {
        this.activityId = activityId;
        this.unionGroup = unionGroup;
    }

    public int getActivityId() {
        return activityId;
    }

    public int getUnionGroup() {
        return unionGroup;
    }

    public void addSyncPatronsAbility(GamePlayer player, List<UserPatrons> patronsList) {
        String unionId = GameUnionActivityGroupMgr.getUnionUid(activityId, player.getUserId());
        if (StringUtils.isNullOrEmpty(unionId)) {
            return;
        }

        //晋级的联盟id
        if (joinUnionList.isEmpty() || !joinUnionList.contains(unionId)) {
            return;
        }
        synchronized (needUploadObjectInfoMap) {
            Set<Integer> set = needUploadObjectInfoMap.get(player.getUserId());
            if (set == null) {
                set = new HashSet();
                needUploadObjectInfoMap.put(player.getUserId(), set);
            }
            for (UserPatrons patrons : patronsList) {
                set.add(patrons.getPatronsId());
            }
        }
    }

    /**
     * 同步门客数据
     */
    public void uploadObjectInfo() {
        synchronized (needUploadObjectInfoMap) {
            if (needUploadObjectInfoMap.size() <= 0) {
                return;
            }
            PeakSeacraftProto.PeakSeacraftSynUserInfoGameToCrossMsg.Builder synUserMsg = PeakSeacraftProto.PeakSeacraftSynUserInfoGameToCrossMsg.newBuilder();
            synUserMsg.setActivityId(activityId);
            for (Map.Entry<Long, Set<Integer>> entry : needUploadObjectInfoMap.entrySet()) {
                long userId = entry.getKey();
                GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
                if (player == null) {
                    continue;
                }
                PeakSeacraftProto.PeakSeacraftSynUserPatronsInfo.Builder userPatronsInfo = PeakSeacraftProto.PeakSeacraftSynUserPatronsInfo.newBuilder();
                userPatronsInfo.setUserId(player.getUserId());
                for (Integer patronsId : entry.getValue()) {
                    PatronsModule patronsModule = player.getModule(PatronsModule.class);
                    UserPatrons userPatrons = patronsModule.getUserPatrons(patronsId);
                    if (userPatrons != null) {
                        userPatronsInfo.addPatronsList(PeakSeacraftMgr.builderPeakSeacraftPatronsEntity(userPatrons));
                    }
                }
                synUserMsg.addUserPatronsList(userPatronsInfo);

            }
            if (synUserMsg.getUserPatronsListCount() > 0) {
                GamePlayerMgr.sendUnionActivityGroupPacket(CrossProtocol.C_PEAK_SEACRAFT_SYN_PATRONS_INFO, synUserMsg, 0, activityId, unionGroup);
            }
            needUploadObjectInfoMap.clear();
        }
    }

    /**
     * 是否晋级
     *
     * @return
     */
    public boolean isPromotion(String unionId) {
        return joinUnionList.contains(unionId);
    }


    public synchronized void lockJoinUnionFromCross(PeakSeacraftProto.PeakSeacraftSynPromotionUnionCrossToGameMsg crossToGameMsg) {
        int activityId = crossToGameMsg.getActivityId();

        PeakSeacraftMgr.getLogger().info("收到锁定晋级 南海丝路 的联盟名额 activityId：{},需要同步的联盟returnUnionInfoListList:{},userTeamInfoList：{}",
                activityId, StringUtils.listToString(crossToGameMsg.getReturnUnionInfoListList(), ","), StringUtils.listToString(crossToGameMsg.getReturnUserTeamListList(), ","));
        // 过滤不属于当前区服的活动
        if (this.activityId != activityId) {
            PeakSeacraftMgr.getLogger().info("过滤不属于当前区服的活动 curActivityId : {}", activityId);
            return;
        }
        List<String> promotionList = crossToGameMsg.getUnionIdList();
        PeakSeacraftMgr.getLogger().info("收到锁定晋级 南海丝路 的联盟名额 activityId：{},round:{},晋级联盟unionList:{}",
                activityId, StringUtils.listToString(promotionList, ","));
        if (joinUnionList.isEmpty()) {
            // 同步玩家数据
            for (String unionId : promotionList) {
                CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfoMap().get(unionId);
                Map<Long, CrossUnionMember> memberMap = CrossUnionMgr.getUnionMemberMap(unionId);
                if (unionInfo != null && memberMap != null) {
                    for (CrossUnionMember item : memberMap.values()) {
                        GamePlayer member = GamePlayerMgr.getOnlinePlayer(item.getUserId());
                        if (member != null) {
                            member.getModule(PeakSeacraftModule.class).synUserData();
                        }
                    }
                }
            }
        }
        joinUnionList.clear();
        joinUnionList.addAll(promotionList);

        int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());
        PeakSeacraftProto.PeakSeacraftSynPromotionUnionGameToCrossMsg.Builder toCrossMsg = PeakSeacraftProto.PeakSeacraftSynPromotionUnionGameToCrossMsg.newBuilder();
        toCrossMsg.setActivityId(activityId);
        if (crossToGameMsg.getReturnUnionInfoListList().size() > 0) {
            // 返回需要同步的联盟数据 以及玩家数据
            for (String unionId : crossToGameMsg.getReturnUnionInfoListList()) {
                CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfoMap().get(unionId);
                if (unionInfo != null) {
                    UserInfo masterUser = UserMgr.getUserInfo(unionInfo.getMasterUserId());
                    if (masterUser == null) {
                        continue;
                    }
                    PeakSeacraftProto.PeakSeacraftUnionInfo.Builder seacraftSouthSeaUnionInfo = PeakSeacraftProto.PeakSeacraftUnionInfo.newBuilder();
                    seacraftSouthSeaUnionInfo.setUnionId(unionId);
                    UnionBaseInfo unionBaseInfo = CrossUnionMgr.parseUnionBaseInfo(unionInfo);
                    UnionProto.UnionBaseTempMsg.Builder unionMsg = UnionBasePb.parseUnionBaseTempMsg(unionBaseInfo);
                    seacraftSouthSeaUnionInfo.setUnionBaseInfo(unionMsg);
                    // 联盟信息
                    Map<Long, CrossUnionMember> memberMap = CrossUnionMgr.getUnionMemberMap(unionId);
                    if (memberMap != null) {
                        for (CrossUnionMember member : memberMap.values()) {
                            PeakSeacraftProto.PeakSeacraftUnionMemberInfo.Builder memberInfo = PeakSeacraftProto.PeakSeacraftUnionMemberInfo.newBuilder();
                            memberInfo.setServerId(member.getServerId());
                            memberInfo.setUserId(member.getUserId());
                            memberInfo.setPosition(member.getPosition());
                            seacraftSouthSeaUnionInfo.addMemberInfoList(memberInfo);
                        }
                    }
                    toCrossMsg.addUnionList(seacraftSouthSeaUnionInfo);
                }
            }
        }
        // 返回门客数据
        if (crossToGameMsg.getReturnUserTeamListList().size() > 0) {
            for (long userId : crossToGameMsg.getReturnUserTeamListList()) {
                // 同步锁定联盟的联盟成员给跨服
                UserBaseInfo userBaseInfo = UserMgr.getUserBaseInfo(userId, GameServer.getInstance().getServerId());
                if (userBaseInfo == null) {
                    continue;
                }
                PeakSeacraftProto.PeakSeacraftLockUserInfo.Builder memberInfo = PeakSeacraftProto.PeakSeacraftLockUserInfo.newBuilder();
                memberInfo.setUserId(userId);
                memberInfo.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                // 锁定 队伍
                Map<Integer, List<UserPatrons>> patronMap = PeakSeacraftMgr.getPatronsMap(userId);
                for (Map.Entry<Integer, List<UserPatrons>> entry : patronMap.entrySet()) {
                    PeakSeacraftProto.PeakSeacraftLockTeamInfo.Builder teamInfo = PeakSeacraftProto.PeakSeacraftLockTeamInfo.newBuilder();
                    teamInfo.setType(entry.getKey());
                    entry.getValue().forEach(e -> {
                        if (teamInfo.getPatronsBuilderList().size() >= SeacraftSouthSeaActivityConfig.getTeamNum()) {
                            // 只取前六名
                            return;
                        }
                        teamInfo.addPatrons(PeakSeacraftMgr.builderPeakSeacraftPatronsEntity(e));
                    });
                    memberInfo.addTeamInfo(teamInfo);
                }
                toCrossMsg.addUserTeamInfoList(memberInfo);
            }
        }
        if (toCrossMsg.getUnionListList().size() > 0 || toCrossMsg.getUserTeamInfoListList().size() > 0) {
            GamePlayerMgr.sendUnionActivityGroupPacket(CrossProtocol.C_PEAK_SEACRAFT_SYN_PROMOTION_UNION, toCrossMsg, 0, activityId, unionGroup);
        }
    }

    /**
     * 向跨服索要晋级联盟的数据
     */
    public synchronized void getPromotionUnionList() {
        if (!PeakSeacraftMgr.hasActivity()) {
            return;
        }
        int round = PeakSeacraftMgr.getConfig().getCurRound();
        if (round <= 0) {
            if (joinUnionList.size() != 0) {
                joinUnionList.clear();
            }
            return;
        }
        if (joinUnionList.isEmpty()) {
            PeakSeacraftProto.PeakSeacraftGetPromotionUnionGameToCrossMsg.Builder builder = PeakSeacraftProto.PeakSeacraftGetPromotionUnionGameToCrossMsg.newBuilder();
            builder.setActivityId(activityId);
            GamePlayerMgr.sendUnionActivityGroupPacket(CrossProtocol.C_PEAK_SEACRAFT_GET_PROMOTION_UNION, builder, 0, activityId, unionGroup);
        }
    }

    /**
     * 当前阶段是否能进出商会 或解散商会
     *
     * @param unionId
     * @return
     */
    public boolean canInAndOutUnion(String unionId) {
        //名单还没同步下来的时候不能操作商会
        if (joinUnionList.isEmpty()) {
            return false;
        }

        return !joinUnionList.contains(unionId);
    }

    public List<String> getJoinUnionList() {
        return joinUnionList;
    }

    /**
     * 同步联盟信息
     *
     * @param type
     * @param unionId
     * @param userId
     * @param position
     */
    public void synUnionInfo(int type, String unionId, long userId, int position) {
        try {
            PeakSeacraftActivityConfig config = PeakSeacraftMgr.getConfig();
            // 联盟信息改变
            int curRound = config.getCurRound();
            if (curRound == 0 || curRound > config.getMaxRoundCount()) {
                // 不在 海盗之乱结束- 南海丝路结束 区间
                return;
            }
            // 晋级名单
            if (joinUnionList.isEmpty() || !joinUnionList.contains(unionId)) {
                return;
            }
            PeakSeacraftProto.PeakSeacraftSynUnionMemberGameToCrossMsg.Builder synUnionMemberGameToCrossMsg = PeakSeacraftProto.PeakSeacraftSynUnionMemberGameToCrossMsg.newBuilder();
            synUnionMemberGameToCrossMsg.setActivityId(activityId);
            synUnionMemberGameToCrossMsg.setType(type);
            synUnionMemberGameToCrossMsg.setUnionId(unionId);
            UnionBaseInfo unionBaseInfo = CrossUnionMgr.parseUnionBaseInfo(unionId);

            UnionProto.UnionBaseTempMsg.Builder unionMsg = UnionBasePb.parseUnionBaseTempMsg(unionBaseInfo);
            synUnionMemberGameToCrossMsg.setUnionInfo(unionMsg);

            if (type == eUnionSyncType.SetPosition.getValue()) {
                if (userId == unionBaseInfo.getMasterUserId()) {//会长变更全部职位更新一下
                    for (CrossUnionMember member : CrossUnionMgr.getUnionMemberMap(unionId).values()) {
                        synUnionMemberGameToCrossMsg.addMemberPosition(PeakSeacraftProto.PeakSeacraftMemberPositionTemp.newBuilder().setUserId(member.getUserId()).setPosition(member.getPosition()));
                    }
                } else {
                    synUnionMemberGameToCrossMsg.addMemberPosition(PeakSeacraftProto.PeakSeacraftMemberPositionTemp.newBuilder().setUserId(userId).setPosition(position));
                }
            }

            GamePlayerMgr.sendUnionActivityGroupPacket(CrossProtocol.C_PEAK_SEACRAFT_SYN_UNION_MEMBER_CHANGE, synUnionMemberGameToCrossMsg, 0, activityId, unionGroup);

        } catch (Exception e) {
            PeakSeacraftMgr.getLogger().error("同步海上争霸 联盟数据 error", e);
        }
    }

    public void exit(long userId) {
        synchronized (inActivitySet) {
            for (Set<Long> userIdSet : inActivitySet.values()) {
                if (userIdSet.contains(userId)) {
                    userIdSet.remove(userId);
                    break;
                }
            }
        }
    }

    public void enter(long userId, int area, int group) {
        int key = area * 100 + group;
        synchronized (inActivitySet) {
            Set<Long> userIdSet = inActivitySet.get(key);
            if (null == userIdSet) {
                userIdSet = new ConcurrentHashSet<>();
                inActivitySet.put(key, userIdSet);
            }
            userIdSet.add(userId);
        }
    }

    /**
     * 对进入系统的玩家广播
     */
    public void Broadcast(PeakSeacraftProto.PeakSeacraftBroadcastCrossToGameMsg msg) {
        int key = msg.getArea() * 100 + msg.getGroup();
        Set<Long> userIdSet = inActivitySet.get(key);
        if (null == userIdSet) {
            return;
        }
        synchronized (inActivitySet) {
            PeakSeacraftProto.BroadcastPeakSeacraftRespMsg.Builder broadcast = msg.getBroadcastMsg().toBuilder();
            if (msg.getNeedBroadcastIdsCount() > 0) {
                for (Long userId : msg.getNeedBroadcastIdsList()) {
                    if (userIdSet.contains(userId)) {
                        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
                        if (player != null) {
                            player.sendPacket(ClientProtocol.U_PEAK_SEACRAFT_BROADCAST, broadcast);
                        }
                    }
                }
            } else {
                List<Long> userIds = new ArrayList<>();
                userIds.addAll(userIdSet);
                for (Long userId : userIds) {
                    if (msg.getExcludeIdsList().contains(userId)) {
                        continue;
                    }
                    GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
                    if (player != null) {
                        player.sendPacket(ClientProtocol.U_PEAK_SEACRAFT_BROADCAST, broadcast);
                    }
                }
            }
        }
    }
}
